Skip to content

SwiftBuild: Fix executable can't find dynamic lib runtime error #8650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 15, 2025

Conversation

pmattos
Copy link
Contributor

@pmattos pmattos commented May 10, 2025

Update LD_RUNPATH_SEARCH_PATHS of executable built using the new Swift Build backend.

Motivation:

For the Swift Build backend, fix a runtime issue when building & running an executable linked against a dynamic library. Given the following packages:

Package App

let package = Package(
    name: "App",
    dependencies: [
        .package(path: "../Lib")
    ],
    targets: [
        .executableTarget(
            name: "App",
            dependencies: [
                .product(name: "Utils", package: "Lib")
            ]
        )
    ]
)

Package Lib

let package = Package(
    name: "Lib",
    products: [
        .library(
            name: "Utils",
            type: .dynamic,
            targets: ["Utils"]
        )
    ],
    targets: [
        .target(name: "Utils")
    ]
)

This the error that I get:

$ swift run --package-path /App --build-system swiftbuild

dyld[89079]: Library not loaded: @rpath/libUtils.dylib
Referenced from: 
<98AF2F50-2C62-318C-8430-C6326D8468F1> /App/.build/arm64-apple-macosx/Products/Debug/App
Reason: tried: 
'/usr/lib/swift/libUtils.dylib' (no such file, not in dyld cache), 
'/App/.build/arm64-apple-macosx/Products/Debug/PackageFrameworks/libUtils.dylib' (no such file),
'/System/Volumes/Preboot/Cryptexes/OS/usr/lib/swift/libUtils.dylib' (no such file), 
'/System/Volumes/Preboot/Cryptexes/OS/App/.build/arm64-apple-macosx/Products/Debug/PackageFrameworks/libUtils.dylib' (no such file),

...but works just fine when using --build-system native.

When comparing the runpath, we get this:

# Swift Build
.build/arm64-apple-macosx/Products/Debug/App
/usr/lib/swift
/Users/pmattos/SamplePackages/App+DynamicLib/App/.build/arm64-apple-macosx/Products/Debug/PackageFrameworks

# Native
.build/arm64-apple-macosx/debug/App
/usr/lib/swift
@loader_path
/Applications/Xcode_17A233.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.5/macosx

PS. To get the runpath, run otool -l path/to/bin | awk '/LC_RPATH/ {getline; getline; print $2}'.

Modifications:

Update the build setting LD_RUNPATH_SEARCH_PATHS for executables, appending @loader_path. This is actually an "imparted" build setting coming from dynamic libraries targets, so that's where I made the change.

Result:

Now both configurations are capable of running the built App:

$ swift run --package-path /App --build-system swiftbuild --configuration debug
Hello from Lib

$ swift run --package-path /App --build-system swiftbuild --configuration release
Hello from Lib

For reference, this is the PIF for the sample package App above. Note my change affects the bottom PACKAGE-TARGET:Utils target only. The build setting is then "imparted" on the top PACKAGE-PRODUCT:App target.

@pmattos pmattos changed the title SwiftBuild: Fix executable can't find dynamic lib SwiftBuild: Fix executable can't find dynamic lib error May 10, 2025
@pmattos pmattos changed the title SwiftBuild: Fix executable can't find dynamic lib error SwiftBuild: Fix executable can't find dynamic lib runtime error May 10, 2025
@pmattos
Copy link
Contributor Author

pmattos commented May 10, 2025

@swift-ci test

@pmattos
Copy link
Contributor Author

pmattos commented May 13, 2025

@swift-ci test

@pmattos
Copy link
Contributor Author

pmattos commented May 13, 2025

@swift-ci test self hosted windows

@pmattos pmattos requested a review from jakepetroules May 13, 2025 20:52
@pmattos
Copy link
Contributor Author

pmattos commented May 14, 2025

@swift-ci test windows

Copy link
Contributor

@bkhouri bkhouri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Thank you for fixing this issue, however can we please ensure there is a test accompanying this change to ensure we don't regress?

I'm fine if you want to create a follow-up PR that adds the test, but I'd like to see a reference to the added test before merging this PR.

@pmattos
Copy link
Contributor Author

pmattos commented May 14, 2025

praise: Thank you for fixing this issue, however can we please ensure there is a test accompanying this change to ensure we don't regress?

I'm fine if you want to create a follow-up PR that adds the test, but I'd like to see a reference to the added test before merging this PR.

It's a good point! I added #8672 to track this 👍🏼

@pmattos pmattos requested a review from bkhouri May 14, 2025 20:33
@pmattos pmattos merged commit c5009fd into main May 15, 2025
6 checks passed
@pmattos pmattos deleted the pmattos/executable-rpath-on-swiftbuild branch May 15, 2025 00:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants